package org.langcom.logic.automata;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public abstract class AbstractAutomata<T> implements IAutomataState<T> {

	private T item;
	private Set<String> actionSet = new HashSet<String>();
	private boolean progibited = false;
	private Map<String, ActionWrapper[]> wrapperMap = new HashMap<String, ActionWrapper[]>();

	public AbstractAutomata(T item) {
		this.item = item;
	}

	@Override
	public T getItem() {
		return item;
	}

	@Override
	public void evaluate(String actionName) throws ActionUnavailableException {
		if (actionSet.contains(actionName)) {
			if (progibited) {
				throw new ActionUnavailableException();
			}
		} else {
			if (!progibited) {
				throw new ActionUnavailableException();
			}
		}
	}

	@Override
	public boolean evaluateSilent(String actionName) {
		if (actionSet.contains(actionName)) {
			return !progibited;
		} else {
			return progibited;
		}
	}

	public void executeBefore(String actionName) {
		for (ActionWrapper wrapper : wrapperMap.get(actionName)) {
			wrapper.beforeInvoke();
		}
	}

	public void executeAfter(String actionName) {
		for (ActionWrapper wrapper : wrapperMap.get(actionName)) {
			wrapper.afterInvoke();
		}
	}

	protected void setEvaluated(String actionName, ActionWrapper... wrappers) {
		actionSet.add(actionName);
		if (wrappers != null && wrappers.length > 0) {
			wrapperMap.put(actionName, wrappers);
		}
	}

	@Override
	public void process() {
		actionSet.clear();
		wrapperMap.clear();
		setAllPrivate();
	}

	protected void setAllPublic() {
		this.progibited = false;
	}

	protected void setAllPrivate() {
		this.progibited = true;
	}
}
